package com.santoker.user.service.controller;

import com.alibaba.fastjson.JSON;
import com.santoker.baseservice.ApiResponseBody;
import com.santoker.baseservice.ApiResponseCode;
import com.santoker.baseservice.redis.AuthInfo;
import com.santoker.user.service.exception.CommonServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.List;

@Slf4j
public abstract class BaseController {

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ApiResponseBody handleException(HttpServletRequest request,
                                           Exception ex,
                                           HttpServletResponse response) {
        String uri = "";
        if (StringUtils.isNotEmpty(request.getRequestURI())) {
            uri = request.getRequestURI();
        }
        if (ex instanceof IOException) {
            log.error(getLogError(ex.getMessage(), request));
            log.info("IOException 客户端读取数据超时 已关闭连接 url: {} ", uri);
        } else {
            log.error(getLogError(ex.getMessage(), request));
            log.error("未处理异常: " + uri, ex);
        }

        return ApiResponseBody.create(ApiResponseCode.SYSTEM_ERROR.getCode(), "请求出错!", null);
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ApiResponseBody handleParameterMissingException(HttpServletRequest request,
                                                           MissingServletRequestParameterException ex,
                                                           HttpServletResponse response) {

        log.error(getLogError(ex.getMessage(), request));
        log.error("wrong code: " + ApiResponseCode.PARAM_ILLEGAL.getCode() + ", msg: " + ex.getMessage());
        return ApiResponseBody.create(ApiResponseCode.PARAM_ILLEGAL.getCode(), ex.getMessage(), null);
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ApiResponseBody handleParameterNotReadableException(HttpServletRequest request,
                                                               HttpMessageNotReadableException ex,
                                                               HttpServletResponse response) {
        log.error(getLogError(ex.getMessage(), request));
        log.error("wrong code: " + ApiResponseCode.PARAM_ILLEGAL.getCode() + ", msg: " + ex.getMessage());
        return ApiResponseBody.create(ApiResponseCode.PARAM_ILLEGAL.getCode(), ApiResponseCode.PARAM_ILLEGAL.getMsg(), null);
    }

    @ExceptionHandler(CommonServiceException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ApiResponseBody handleServiceException(HttpServletRequest request,
                                                  CommonServiceException ex,
                                                  HttpServletResponse response) {
        log.error(getLogError(ex.getMessage(), request));
        return ApiResponseBody.create(ex.getCode(), ex.getMessage(), null);
    }

    /**
     * 校验参数
     *
     * @param result
     * @return
     */
    protected void validParams(BindingResult result) {
        List<FieldError> errors = result.getFieldErrors();
        for (FieldError error : errors) {
            throw new CommonServiceException(ApiResponseCode.PARAM_ILLEGAL.getCode(), error.getDefaultMessage());
        }
    }

    public String getLogError(String msg, HttpServletRequest request) {
        StringBuilder builder = new StringBuilder();
        builder.append("api:").append(request.getRequestURI()).append(", ");
        builder.append("msg:").append(msg).append(", ");
        return builder.toString();
    }

    /**
     * 获取登陆用户信息
     *
     * @param request
     * @return
     */
    public AuthInfo getAuthInfo(HttpServletRequest request) {
        try {
            String userJson = URLDecoder.decode(request.getHeader("user"), "UTF-8");
            return JSON.parseObject(userJson, AuthInfo.class);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CommonServiceException(ApiResponseCode.NOT_AUTHORIZED);
        }
    }

}
